1 /*
2  * Collie - An asynchronous event-driven network framework using Dlang development
3  *
4  * Copyright (C) 2015-2017  Shanghai Putao Technology Co., Ltd 
5  *
6  * Developer: putao's Dlang team
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 module collie.net.server.connection;
12 
13 import kiss.net.TcpStream;
14 import kiss.event.timer.common;
15 import kiss.util.timer;
16 import kiss.event;
17 import kiss.event.task;
18 import kiss.logger;
19 
20 
21 abstract class ServerConnection : WheelTimer
22 {
23 	this(TcpStream socket)
24 	{
25 		resetSocket(socket);
26 	}
27 
28 	final void resetSocket(TcpStream socket)
29 	{
30 		if(_socket !is null){
31 			_socket.onClosed(null);
32 			_socket.onDataReceived(null);
33 			_socket = null;
34 		}
35 		if(socket !is null){
36 			_socket = socket;
37 			_loop = cast(EventLoop) socket.eventLoop;
38 			_socket.onClosed(&doClose);
39 			_socket.onDataReceived(&onRead);
40 		}
41 	}
42 
43 	final bool isAlive() @trusted {
44 		return _socket && _socket.isRegistered;
45 	}
46 
47 	final bool active() @trusted
48 	{
49 		if(_socket is null)
50 			return false;
51 		_socket.start();
52 		onActive();
53 		return true;
54 	}
55 
56 	final void write(ubyte[] data, DataWrittenHandler cback = null) @trusted
57 	{
58 		write(new SocketStreamBuffer(data,cback));
59 	}
60 
61 	final void write(StreamWriteBuffer buffer)
62     {
63         if (_loop.isInLoopThread()) {
64             _postWriteBuffer(buffer);
65         } else {
66             _loop.postTask(newTask(&_postWriteBuffer, buffer));
67         }
68     }
69 
70 	final void restTimeout() @trusted
71 	{
72 		if(_loop.isInLoopThread()){
73 			rest();
74 		} else {
75 			_loop.postTask(newTask(&rest,0));
76 		}
77 	}
78 	pragma(inline)
79 	final void close() @trusted
80 	{
81 		_loop.postTask(newTask(&_postClose));
82 	}
83 
84 	final @property TcpStream tcpStream()@safe {
85 		assert(_socket !is null);
86 		return _socket;
87 		}
88 protected:
89 	void onActive() nothrow;
90 	void onClose() nothrow;
91 	void onRead(in ubyte[] data) nothrow;
92 
93 private:
94 	final void _postClose(){
95 		if(_socket)
96 			_socket.close();
97 	}
98 
99  	final void _postWriteBuffer(StreamWriteBuffer buffer)
100     {
101         if (_socket) {
102 			version (CollieDebugMode) logDebug("posting data...  ", buffer);
103             rest();
104             _socket.write(buffer);
105         } else
106 		{
107 			version (CollieDebugMode) logDebug("post done.");
108             buffer.doFinish();
109 		}
110     }
111 
112 	final void doClose() 
113 	{
114 		stop();
115 		onClose();
116 	}
117 private:
118 	TcpStream _socket;
119 	EventLoop _loop;
120 }
121